package org.jeecg.modules.jx.utils;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 从配置文件中读取各种 加密的文本，然后在 post construct 后进行解密，此类会生成一个唯一的实例bean，可以被其他需要使用解密后参数的 bean依赖
 */
@Component
@Slf4j
public class JxCryptUtil {

    @Value("${wx.encrypted.app-id}")
    private String encryptedAppId;

    // 解密后的 appId，明文
    public String appId;

    @Value("${wx.encrypted.secret}")
    private String encryptedAppSecret;

    // 解密后的 appSecret，明文
    public String appSecret;

    private static final String ENCRYPTION_ALGORITHM = "AES";
    private static final String CUSTOMER_MINI_APP_SECRET_KEY = "1234567890ABCDEF"; // 密钥，需要与加密时使用的密钥一致

    // 对商户密码进行加密的 密钥使用其他的密钥； 对当前应用中，不同类型的需要保密的数据，使用不同的密钥；若密钥相同，则一旦丢失，则所有保密数据都会受到影响
    private static final String MERCHANT_PASS_ENCRYPT_KEY = "ASDFGH0963852741";

    /**
     * 参考链接：
     * https://developer.aliyun.com/article/1378313
     */
    @PostConstruct
    public void decrpytAllConfidentialText() {
        appId = decrypt(encryptedAppId, CUSTOMER_MINI_APP_SECRET_KEY);
        appSecret = decrypt(encryptedAppSecret, CUSTOMER_MINI_APP_SECRET_KEY);

        log.info("decrypted app id: {}", appId);
        log.info("decrypted app secret: {}", appSecret);
    }

    public String decrypt(String encryptedPassword, String secretKey) {
        try {
            byte[] encryptedPasswordBytes = Base64.getDecoder().decode(encryptedPassword);
            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
            SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), ENCRYPTION_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] decryptedPasswordBytes = cipher.doFinal(encryptedPasswordBytes);
            return new String(decryptedPasswordBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 对商户登录密码进行解密
     * @param encryptedPassword
     * @return
     */
    public String decryptMerchantPassword(String encryptedPassword) {

        return decrypt(encryptedPassword, MERCHANT_PASS_ENCRYPT_KEY);
    }

    public String encrypt(String password, String secretKey) {
        try {
            Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
            SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), ENCRYPTION_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] encryptedPasswordBytes = cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedPasswordBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public String encryptMerchantPassword(String password){
        return encrypt(password, MERCHANT_PASS_ENCRYPT_KEY);
    }
}
